﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace VNTG.UserProfileFilters
{
    /// <summary>
    /// Helper class with some common reflection stuff.
    /// </summary>
    public class ReflectionHelper
    {
        /// <summary>
        /// Create a generic object using reflection.
        /// </summary>
        /// <param name="generic">Generic object's type (e.g. List&lt;&gt;)</param>
        /// <param name="innerType">Type contained in the generic</param>
        /// <param name="args">Arguments to pass to the generic's constructor</param>
        /// <returns></returns>
        /// <remarks>Used to create generic lists of internal classes</remarks>
        public static object CreateGeneric(Type generic, Type innerType, params object[] args)
        {
            Type specificType = generic.MakeGenericType(new Type[] { innerType });
            return Activator.CreateInstance(specificType, args);
        }

        /// <summary>
        /// Set a property using reflection.
        /// </summary>
        /// <param name="target">Object to set the property on</param>
        /// <param name="objType">Object's type</param>
        /// <param name="propertyName">Name of the property</param>
        /// <param name="propertyValue">Value of the property</param>
        public static void SetPropertyValue(object target, Type objType, string propertyName, object propertyValue)
        {
            PropertyInfo pi = objType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            pi.SetValue(target, propertyValue, null);
        }

        /// <summary>
        /// Get an enum object corresponding to the given string-value.
        /// </summary>
        /// <param name="enumType">Enum type</param>
        /// <param name="value">Value to retrieve from enum</param>
        /// <returns></returns>
        public static object GetEnumValue(Type enumType, string value)
        {
            var result = Activator.CreateInstance(enumType); // Get a default value
            foreach (FieldInfo fInfo in enumType.GetFields(BindingFlags.Public | BindingFlags.Static))
            {
                if (fInfo.FieldType.IsEnum &&
                    fInfo.Name.Equals(value, StringComparison.OrdinalIgnoreCase))
                {
                    result = fInfo.GetRawConstantValue();
                }
            }
            return result;
        }
    }
}
